
import { ErrorPayload, ResponsePayload, SendToPayload, SendToRoomPayload, isErrorPayload, isSendToPayload, isSendToRoomMessage, isSendToRoomPayload } from '@core/types'
import { publishToQueue, publishToTopic } from '@nodejs/mq'
import { errorToBuffer, loadProto, responseToBuffer, sendToBuffer, sendToRoomBuffer } from './proto'
export async function sendToResponse(root: protobuf.Root, payload: ResponsePayload | ErrorPayload | SendToPayload | SendToRoomPayload) {
    if (isErrorPayload(payload)) {
        const buf = errorToBuffer(root, payload)
        return await publishToTopic('response.topic', `response.${payload.appid}`, buf, {})
    } else if (isSendToPayload(payload)) {
        const buf = sendToBuffer(root, payload)
        return await publishToQueue('ws.room.response', buf, {
            durable: true,
            autoDelete: false,
            exclusive: false,
            arguments: {
                'x-queue-type': 'stream'
            }
        })
    } else if (isSendToRoomPayload(payload)) {
        const buf = sendToRoomBuffer(root, payload)
        return await publishToQueue(payload.roomid, buf, {
            durable: true,
            autoDelete: false,
            exclusive: false,
            arguments: {
                'x-queue-type': 'stream'
            }
        })
    } else {
        const buf = responseToBuffer(root, payload)
        return await publishToTopic('response.topic', `response.${payload.appid}`, buf, {})
    }
}

export async function sendTo(root: protobuf.Root, payload: SendToPayload) {
    const buf = sendToBuffer(root, payload)
    return await publishToTopic('response.topic', `response.${payload.to}`, buf, {})
}

export async function sendToRoom(root: protobuf.Root, payload: SendToRoomPayload) {
    const buf = sendToRoomBuffer(root, payload)
    return await publishToTopic('response.topic', `response.${payload.roomid}`, buf, {})
}

export async function createSender() {
    const proto = await loadProto()
    return (payload: ResponsePayload | ErrorPayload | SendToPayload | SendToRoomPayload) => {
        return sendToResponse(proto, payload)
    }
}